package edu.usc.csci578.project.util.parse;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Logger;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;

/**
 * Class responsible for parsing a given XML file into the appropriate Jaxb
 * object.
 */
public class XMLJaxbParser
{
	/**
	 * Default folder for all XML files
	 */
	public final static String XML_HOME = "target/classes/xml/";
	/**
	 * Jaxb context to use to construct the Jaxb objects
	 */
	private final String context;
	/**
	 * Logger for this class
	 */
	private final Logger LOG = Logger.getLogger(this.getClass().getName());
	/**
	 * XML file to read from
	 */
	private final String xmlFilePath;

	/**
	 * Constructs a XMLJaxbParser for a given filename and Jaxb context (package
	 * of the Jaxb objects to create)
	 * 
	 * @param xmlFilePath
	 *            name of the XML file to parse
	 * @param context
	 *            Jaxb context (package)
	 */
	public XMLJaxbParser(final String xmlFilePath, final String context)
	{
		this.xmlFilePath = xmlFilePath;
		this.context = context;
	}

	/**
	 * Parses the XML file, creating an instance of the passed in Jaxb object
	 * representing the root of the XML file
	 * 
	 * @param generic
	 *            expected type of the root element of the XML file
	 * @return the Jaxb element representing the root of the XML file
	 * @throws FileNotFoundException
	 *             if the XML file is not found
	 */
	protected JAXBElement<?> unmarshalXML(final Class<?> generic)
			throws FileNotFoundException
	{
		final File xmlFile = new File(xmlFilePath);
		LOG.info("Reading in the XML data from " + xmlFile.getAbsolutePath());
		FileInputStream stream = null;
		try
		{
			final JAXBContext jc = JAXBContext.newInstance(context);
			final Unmarshaller u = jc.createUnmarshaller();
			// Get Delivery Manifest object
			stream = new FileInputStream(xmlFile);
			final JAXBElement<?> rootElement = u.unmarshal(new StreamSource(
					stream), generic);
			return rootElement;
		} catch (final JAXBException e)
		{
			LOG.warning(e.getMessage());
		} finally
		{
			try
			{
				if (stream != null)
					stream.close();
			} catch (final IOException e)
			{
				e.printStackTrace();
			}
		}
		LOG.info("Unmarshalling complete.");
		return null;
	}
}
